import type { App } from 'vue'
import { useUserStore } from '@/stores/user'

// 定义页面实例类型
interface PageInstance {
  route: string
  options: Record<string, string>
}

// 白名单路由（支持正则匹配）
const whiteList = [
  '/pages/index/index',
  '/pages/error/index',
  '/pages/privacy/index',
  // 支持通配符
  /^\/pages\/public\/.*/, // 所有 public 目录下的页面
  /^\/pages\/login\/.*/,
]

// 检查路由是否在白名单中
function isInWhiteList(url: string): boolean {
  return whiteList.some((pattern) => {
    if (pattern instanceof RegExp) {
      return pattern.test(url)
    }
    return pattern === url
  })
}

// 上次检查时间记录
const lastCheckMap = new Map<string, number>()
// 检查间隔时间（毫秒）
const CHECK_INTERVAL = 1000

// 路由错误类型
enum RouteErrorType {
  AUTH_FAILED = 'AUTH_FAILED',
  PERMISSION_DENIED = 'PERMISSION_DENIED',
  NETWORK_ERROR = 'NETWORK_ERROR',
  PAGE_NOT_FOUND = 'PAGE_NOT_FOUND',
  SYSTEM_ERROR = 'SYSTEM_ERROR',
}

// 检查登录状态和权限
async function checkAuth(url: string): Promise<boolean> {
  // 检查是否在短时间内重复检查
  const now = Date.now()
  const lastCheck = lastCheckMap.get(url) || 0
  if (now - lastCheck < CHECK_INTERVAL) {
    return true
  }
  lastCheckMap.set(url, now)

  const userStore = useUserStore()

  // 白名单直接放行
  if (isInWhiteList(url)) {
    return true
  }

  // 未登录跳转到登录页
  if (!userStore.token) {
    uni.showToast({
      title: '请先登录',
      icon: 'none',
      duration: 2000,
    })

    // 记录要跳转的页面路径
    const redirect = encodeURIComponent(url)
    uni.reLaunch({
      url: `/pages/login/index?redirect=${redirect}`,
    })
    return false
  }

  // 检查用户信息
  if (!userStore.userInfo) {
    try {
      await userStore.getUserInfo()
      // 获取用户权限
      await userStore.fetchPermissions()
    }
    catch (error) {
      console.error('Failed to fetch user info:', error)
      handleAuthError(userStore)
      return false
    }
  }

  // 检查用户权限 TODO 暂时显示的图标就是过滤权限后的
  // const hasPermission = userStore.hasPermission
  // if (!hasPermission('user:view')) {
  //   uni.showToast({
  //     title: '暂无访问权限',
  //     icon: 'none',
  //     duration: 2000,
  //   })
  //   return false
  // }

  return true
}

// 处理认证错误
function handleAuthError(userStore: ReturnType<typeof useUserStore>) {
  uni.showToast({
    title: '登录已过期，请重新登录',
    icon: 'none',
    duration: 2000,
  })
  userStore.logout()
  uni.reLaunch({
    url: '/pages/login/index',
  })
}

// 处理路由错误
function handleRouteError(error: any) {
  console.error('路由错误:', error)

  let errorMessage = '页面跳转失败，请稍后重试'
  let errorType = RouteErrorType.SYSTEM_ERROR

  if (error.errMsg) {
    if (error.errMsg.includes('fail page not found')) {
      errorMessage = '页面不存在'
      errorType = RouteErrorType.PAGE_NOT_FOUND
    }
    else if (error.errMsg.includes('fail network')) {
      errorMessage = '网络连接失败，请检查网络设置'
      errorType = RouteErrorType.NETWORK_ERROR
    }
  }

  uni.showToast({
    title: errorMessage,
    icon: 'none',
    duration: 2000,
  })

  // 记录错误日志
  console.error(`[Route Error] Type: ${errorType}, Message: ${errorMessage}`, error)

  return false
}

// 路由守卫
export function setupRouteGuard(app: App) {
  let isCheckingAuth = false

  // 注册页面生命周期钩子
  app.mixin({
    async onLoad() {
      if (!isCheckingAuth) {
        isCheckingAuth = true
        const pages = getCurrentPages() as PageInstance[]
        const currentPage = pages[pages.length - 1]
        if (currentPage?.route) {
          const url = `/${currentPage.route}`
          await checkAuth(url)
        }
        isCheckingAuth = false
      }
    },
  })

  // 路由跳转守卫
  const list = ['navigateTo', 'redirectTo', 'reLaunch', 'switchTab']
  list.forEach((item) => {
    uni.addInterceptor(item, {
      async invoke(e) {
        if (!e?.url)
          return e
        const url = e.url.split('?')[0]

        // 对于 switchTab，允许通过，在目标页面进行权限检查
        if (item === 'switchTab') {
          return e
        }

        if (!isCheckingAuth) {
          isCheckingAuth = true
          try {
            const result = await checkAuth(url)
            isCheckingAuth = false
            return result ? e : undefined
          }
          catch (error) {
            isCheckingAuth = false
            return handleRouteError(error)
          }
        }
        return e
      },
      fail(err) {
        return handleRouteError(err)
      },
    })
  })
}

// 导出白名单，方便其他地方使用
export { whiteList, isInWhiteList }
